import axios, { AxiosRequestConfig } from 'axios'
import { Toast, Notify, Dialog } from 'vant'
import router from '@/router/index'
import store from '@/store/index'

interface BaseResponse<T = any> {
  code: number
  data: T
  message: string
}
const instance = axios.create({
  baseURL: process.env.VUE_APP_BASE_API
})

//根据当前请求的信息，生成请求 Key
const generateReqKey = (config: AxiosRequestConfig) => {
  const { method, url } = config
  //通过url和method双重校验
  return [method, url].join('&')
}
//把当前请求信息添加到pendingRequest对象中
const pendingRequest = new Map()
const addPendingRequest = (config: AxiosRequestConfig) => {
  const requestKey = generateReqKey(config)
  config.cancelToken =
    config.cancelToken ||
    new axios.CancelToken(cancel => {
      if (!pendingRequest.has(requestKey)) {
        pendingRequest.set(requestKey, cancel)
      }
      store.commit('http/pushToken', { cancelToken: cancel })
    })
}
//检查是否存在重复请求，若存在则取消已发的请求
const removePendingRequest = (config: AxiosRequestConfig) => {
  const requestKey = generateReqKey(config)
  if (pendingRequest.has(requestKey)) {
    const cancelToken = pendingRequest.get(requestKey)
    cancelToken(requestKey)
    pendingRequest.delete(requestKey)
  }
}

instance.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    //断网提示
    if (!navigator.onLine) {
      Notify({ type: 'warning', message: '您的网络故障，请检查!' })
    }
    config.headers['x-request-source'] = 'H5'
    if (localStorage.getItem('token')) {
      config.headers.token = localStorage.getItem('token')
    }
    removePendingRequest(config) // 检查是否存在重复请求，若存在则取消已发的请求
    addPendingRequest(config) // 把当前请求信息添加到pendingRequest对象中
    return config
  },
  error => {
    // console.log('请求拦截error', error)
    return Promise.reject(error)
  }
)

// interface TipsMessage {
//   [propName: number]: string
// }

// const tipsMessage: TipsMessage = {
//   100: '登录失败  用户名密码不对或账号被锁定',
//   101: 'TOKEN失效  Token已失效，请重新调登录接口',
//   102: '参数错误  请根据接口参数要求进行传参',
//   103: '未登录',
//   300: '接口无访问权限  没有权限访问该接口',
//   301: '数据无访问权限  没有权限访问该设备数据',
//   302: '服务到期  设备服务到期 '
// }

instance.interceptors.response.use(
  response => {
    // setTimeout(() => {
    //   hideLoading()
    // }, 200)
    // console.log(response)
    removePendingRequest(response.config) // 从pendingRequest对象中移除请求
    const { code, message } = response.data
    if (code !== 0 && code !== 200) {
      if (code === 1011008 || code === 2020001 || code === 1011006 || code === 1011004) {
        Dialog.alert({
          title: '温馨提示',
          message: '当前用户没有登录或登录失效，需要重新登录'
        }).then(() => {
          localStorage.clear()
          // router.push({ name: 'Login' })
          // store.commit('logout')
          location.reload() // 为了重新实例化vue-router对象 避免bug
        })
      } else if (code === 20330033) {
        // 未设置支付密码
        router.push({
          name: 'SetPayPassword'
        })
      } else {
        Toast.fail(message)
        //  Toast.fail(`${tipsMessage[code]}`)
      }
      return Promise.reject(message)
    } else {
      return response
    }
  },
  error => {
    // setTimeout(() => {
    //   hideLoading()
    // }, 200)
    // console.log('http response - err', error)
    removePendingRequest(error.config || {}) // 从pendingRequest对象中移除请求
    if (axios.isCancel(error)) {
      // console.log('已取消的重复请求：' + error.message)
    } else {
      // 添加异常处理
      Toast.fail('服务器异常，请稍后再试')
    }
    return Promise.reject(error)
  }
)

const request = <T = any>(config: AxiosRequestConfig): Promise<T> => {
  return new Promise((resolve, reject) => {
    instance
      .request<BaseResponse<T>>(Object.assign(config))
      .then(res => resolve(res.data.data))
      .catch(err => reject(err))
  })
}

export default request
